Ideas for ggraph

Layout

Defines how nodes are placed on the plot, so where to put each node.

We can first try with getting x and y coordinates of the geometry list column

library(ggraph)
library(tidygraph)
library(sfnetworks)
library(sf)
library(ggplot2)
graph_layout = roxel %>% 
  as_sfnetwork(directed = F) %>% 
  convert(to_spatial_coordinates)

graph_layout

sf = ggraph:::layout_tbl_graph_manual(
  graph_layout, X, Y, circular = F
)
layout <- create_layout(graph, layout = 'sf')
layout

Nodes and edges

wrap around geom_sf / ggproto layer GeomSf

  • geom_edges_spatial
  • geom_edges_straight
  • geom_nodes_spatial

Integration between ggraph and spatial ggplot2 No need to escape the network ggraph would accept an object of class sfnetwork

library(sfnetworks)
library(tidygraph)
## 
## Attaching package: 'tidygraph'
## The following object is masked from 'package:stats':
## 
##     filter
library(sf)
## Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(ggraph)
## Loading required package: ggplot2
graph = roxel %>% 
  as_sfnetwork(directed = F) %>% convert(to_components)
ggraph(graph, 'focus', focus = node_is_center()) +
  ggforce::geom_circle(
    aes(x0 = 0, y0 = 0, r = r), 
    data.frame(r = 1:20), colour = 'grey'
  ) +
  geom_edge_link() +
  geom_node_point(color = 'orangered') +
  coord_fixed() +
  theme(
    panel.background = element_rect(fill = "transparent"),
    plot.background = element_rect(fill = "transparent", color = NA)
  )

nodes = graph %>% activate(nodes) %>% st_as_sf()
ggraph(graph) +
  geom_sf(data = nodes) 
## Using `stress` as default layout

geom_edge_spatial = function(x) {
  edges = st_as_sf(x, 'edges')
  geom_sf(data = edges)
}

library(ggraph)
ggraph(graph) +
  geom_edge_spatial(graph)
## Using `stress` as default layout

Final thoughts:

New opportunities

  • explore 3D representation, maybe with rayshader
    • this can take a look into st_zm coordinates
  • maybe look into interactive plotting: mapview
library(sfnetworks)
library(ggplot2)
library(sf)
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
roxel
## Simple feature collection with 851 features and 2 fields
## geometry type:  LINESTRING
## dimension:      XY
## bbox:           xmin: 7.522594 ymin: 51.94151 xmax: 7.546705 ymax: 51.9612
## geographic CRS: WGS 84
## # A tibble: 851 x 3
##    name           type                                                  geometry
##    <fct>          <fct>                                         <LINESTRING [°]>
##  1 Havixbecker S~ residen~                (7.533722 51.95556, 7.533461 51.95576)
##  2 Pienersallee   seconda~ (7.532442 51.95422, 7.53236 51.95377, 7.53209 51.953~
##  3 Schulte-Bernd~ residen~ (7.532709 51.95209, 7.532823 51.95239, 7.532869 51.9~
##  4 <NA>           path     (7.540063 51.94468, 7.539696 51.94479, 7.539466 51.9~
##  5 Welsingheide   residen~                 (7.537673 51.9475, 7.537614 51.94562)
##  6 <NA>           footway  (7.543791 51.94733, 7.54369 51.94686, 7.543751 51.94~
##  7 <NA>           footway                  (7.54012 51.94478, 7.539931 51.94514)
##  8 <NA>           path     (7.53822 51.94546, 7.538131 51.94549, 7.538027 51.94~
##  9 <NA>           track    (7.540063 51.94468, 7.540338 51.94468, 7.540591 51.9~
## 10 <NA>           track    (7.5424 51.94599, 7.54205 51.94629, 7.541967 51.9463~
## # ... with 841 more rows
g = ggplot() +
  geom_sf(data = roxel, aes(color = type))

ggplotly(g)